/*
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * RSInput.cpp
 *
 *  Created on: 2010/02/28
 *      Author: Alexandre Pires ( c.alexandre.pires@gmail.com )
 */

#include "RSInput.h"
#include "RSDocument.h"
#include "RSDataSource.h"

namespace Realsphere {

    RSInput::RSInput ( RSInputSemanticType rSemanticType, RSDataSource* rSource ) :
        RSElement ( RS_INPUT_TAG )
    {
        mSemanticType = rSemanticType;
        SetOffset ( 0, false );
        SetSource ( rSource, false );
        SetSet ( 0, false );
    }

    RSInput::~RSInput ()
    {
        mSource = NULL;
    }

    int RSInput::Offset () const
    {
        return mOffset;
    }

    RSInputSemanticType RSInput::SemanticType () const
    {
        return mSemanticType;
    }

    QString RSInput::SemanticTypeStr () const
    {
        return RSInput::InputSemanticTypeToValue ( mSemanticType );
    }

    RSDataSource* RSInput::SourceElement () const
    {
        return mSource;
    }

    QString RSInput::Source () const
    {
        if ( mSource != NULL )
            return mSource->URI();

        return QString::null;
    }

    int RSInput::Set () const
    {
        return mSet;
    }

    bool RSInput::IsRootElement () const
    {
        return false;
    }

    void RSInput::SetOffset ( unsigned int rOffset, bool rEmit )
    {
        mOffset = rOffset;
        if ( rEmit )
            emit OffsetChanged ( mOffset );
    }

    RSError RSInput::SetSource ( RSDataSource* rSource, bool rEmit )
    {
        mSource = rSource;

        if ( rEmit )
            emit SourceChanged ( mSource );

        return RS_NO_ERROR;
    }

    RSError RSInput::SetSource ( const QString& rId, bool rEmit )
    {
        if ( RootElement () == NULL )
            return RS_ROOT_ELEMENT_NOT_DEFINED;

        if ( !RootElement ()->InstanceOf ( RS_DOCUMENT_CLASS ) )
            return RS_UNIMPLEMENTED;

        RSDocument* document = RSDocumentCast ( RootElement() );
        RSDataSource* source = document->GetDataSource ( rId );

        if ( source == NULL )
            return RS_DATA_SOURCE_NOT_DEFINED;

        return SetSource( source, rEmit );
    }

    void RSInput::SetSet ( unsigned int rSet, bool rEmit )
    {
        mSet = rSet;
        if ( rEmit )
            emit SetChanged ( rSet );
    }

    RSError RSInput::BeforeAddChildElement ( RSElement* rChild )
    {
        return RS_NO_CHILD_ALLOWED;
    }

    QString RSInput::InputSemanticTypeToValue ( RSInputSemanticType rSemanticType )
    {
        switch ( rSemanticType )
        {
            case RS_SEMANTIC_BINORMAL:
                return QString ( RS_SEMANTIC_BINORMAL_VALUE );
                break;
            case RS_SEMANTIC_COLOR:
                return QString ( RS_SEMANTIC_COLOR_VALUE );
                break;
            case RS_SEMANTIC_CONTINUITY:
                return QString ( RS_SEMANTIC_CONTINUITY_VALUE );
                break;
            case RS_SEMANTIC_IMAGE:
                return QString ( RS_SEMANTIC_IMAGE_VALUE );
                break;
            case RS_SEMANTIC_INPUT:
                return QString ( RS_SEMANTIC_INPUT_VALUE );
                break;
            case RS_SEMANTIC_IN_TANGENT:
                return QString ( RS_SEMANTIC_IN_TANGENT_VALUE );
                break;
            case RS_SEMANTIC_INTERPOLATION:
                return QString ( RS_SEMANTIC_INTERPOLATION_VALUE );
                break;
            case RS_SEMANTIC_INV_BIND_MATRIX:
                return QString ( RS_SEMANTIC_INV_BIND_MATRIX_VALUE );
                break;
            case RS_SEMANTIC_JOINT:
                return QString ( RS_SEMANTIC_JOINT_VALUE );
                break;
            case RS_SEMANTIC_LINEAR_STEPS:
                return QString ( RS_SEMANTIC_LINEAR_STEPS_VALUE );
                break;
            case RS_SEMANTIC_MORPH_TARGET:
                return QString ( RS_SEMANTIC_MORPH_TARGET_VALUE );
                break;
            case RS_SEMANTIC_MORPH_WEIGHT:
                return QString ( RS_SEMANTIC_MORPH_WEIGHT_VALUE );
                break;
            case RS_SEMANTIC_NORMAL:
                return QString ( RS_SEMANTIC_NORMAL_VALUE );
                break;
            case RS_SEMANTIC_OUTPUT:
                return QString ( RS_SEMANTIC_OUTPUT_VALUE );
                break;
            case RS_SEMANTIC_OUT_TANGENT:
                return QString ( RS_SEMANTIC_OUT_TANGENT_VALUE );
                break;
            case RS_SEMANTIC_POSITION:
                return QString ( RS_SEMANTIC_POSITION_VALUE );
                break;
            case RS_SEMANTIC_TANGENT:
                return QString ( RS_SEMANTIC_TANGENT_VALUE );
                break;
            case RS_SEMANTIC_TEXBINORMAL:
                return QString ( RS_SEMANTIC_TEXBINORMAL_VALUE );
                break;
            case RS_SEMANTIC_TEXCOORD:
                return QString ( RS_SEMANTIC_TEXCOORD_VALUE );
                break;
            case RS_SEMANTIC_TEXTANGENT:
                return QString ( RS_SEMANTIC_TEXTANGENT_VALUE );
                break;
            case RS_SEMANTIC_UV:
                return QString ( RS_SEMANTIC_UV_VALUE );
                break;
            case RS_SEMANTIC_VERTEX:
                return QString ( RS_SEMANTIC_VERTEX_VALUE );
                break;
            case RS_SEMANTIC_WEIGHT:
                return QString ( RS_SEMANTIC_WEIGHT_VALUE );
                break;
            default:
                return QString ( RS_ELEMENT_TAG );
                break;
        }
    }

    RSInputSemanticType RSInput::InputSemanticValueToType ( const QString& rTag )
    {
        if ( rTag == RS_SEMANTIC_BINORMAL_VALUE )
        {
            return RS_SEMANTIC_BINORMAL;
        }
        else if ( rTag == RS_SEMANTIC_COLOR_VALUE )
        {
            return RS_SEMANTIC_COLOR;
        }
        else if ( rTag == RS_SEMANTIC_CONTINUITY_VALUE )
        {
            return RS_SEMANTIC_CONTINUITY;
        }
        else if ( rTag == RS_SEMANTIC_IMAGE_VALUE )
        {
            return RS_SEMANTIC_IMAGE;
        }
        else if ( rTag == RS_SEMANTIC_INPUT_VALUE )
        {
            return RS_SEMANTIC_INPUT;
        }
        else if ( rTag == RS_SEMANTIC_IN_TANGENT_VALUE )
        {
            return RS_SEMANTIC_IN_TANGENT;
        }
        else if ( rTag == RS_SEMANTIC_INTERPOLATION_VALUE )
        {
            return RS_SEMANTIC_INTERPOLATION;
        }
        else if ( rTag == RS_SEMANTIC_INV_BIND_MATRIX_VALUE )
        {
            return RS_SEMANTIC_INV_BIND_MATRIX;
        }
        else if ( rTag == RS_SEMANTIC_JOINT_VALUE )
        {
            return RS_SEMANTIC_JOINT;
        }
        else if ( rTag == RS_SEMANTIC_LINEAR_STEPS_VALUE )
        {
            return RS_SEMANTIC_LINEAR_STEPS;
        }
        else if ( rTag == RS_SEMANTIC_MORPH_TARGET_VALUE )
        {
            return RS_SEMANTIC_MORPH_TARGET;
        }
        else if ( rTag == RS_SEMANTIC_MORPH_WEIGHT_VALUE )
        {
            return RS_SEMANTIC_MORPH_WEIGHT;
        }
        else if ( rTag == RS_SEMANTIC_NORMAL_VALUE )
        {
            return RS_SEMANTIC_NORMAL;
        }
        else if ( rTag == RS_SEMANTIC_OUTPUT_VALUE )
        {
            return RS_SEMANTIC_OUTPUT;
        }
        else if ( rTag == RS_SEMANTIC_OUT_TANGENT_VALUE )
        {
            return RS_SEMANTIC_OUT_TANGENT;
        }
        else if ( rTag == RS_SEMANTIC_POSITION_VALUE )
        {
            return RS_SEMANTIC_POSITION;
        }
        else if ( rTag == RS_SEMANTIC_TANGENT_VALUE )
        {
            return RS_SEMANTIC_TANGENT;
        }
        else if ( rTag == RS_SEMANTIC_TEXBINORMAL_VALUE )
        {
            return RS_SEMANTIC_TEXBINORMAL;
        }
        else if ( rTag == RS_SEMANTIC_TEXCOORD_VALUE )
        {
            return RS_SEMANTIC_TEXCOORD;
        }
        else if ( rTag == RS_SEMANTIC_TEXTANGENT_VALUE )
        {
            return RS_SEMANTIC_TEXTANGENT;
        }
        else if ( rTag == RS_SEMANTIC_UV_VALUE )
        {
            return RS_SEMANTIC_UV;
        }
        else if ( rTag == RS_SEMANTIC_VERTEX_VALUE )
        {
            return RS_SEMANTIC_VERTEX;
        }
        else if ( rTag == RS_SEMANTIC_WEIGHT_VALUE )
        {
            return RS_SEMANTIC_WEIGHT;
        }

        return RS_SEMANTIC_UNKNOWN;
    }
}
